package com.spongeli.user.util;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
/**
 * 用来导出excel工具类
 * @author spongeli
 */
public class ExcelUtil {
	/**
	 * 
	 * @param length
	 *            在内存缓存。存放数据的个数
	 * @param sheetTitle
	 *            标题
	 * @param fileName
	 * 			文件名
	 * @param sheetHeader
	 *            表头集合<key,Value>
	 * @param data
	 *            数据
	 * @author spongeli
	 * @return
	 */
	public static void getWorkBook(int length, String sheetTitle, String fileName,
			List<MapEntry<String, Object>> sheetHeader, List<Map<String, Object>> data, HttpServletResponse response) {

		// 1.0 创建一个excle对象
		/**
		 * 这两个的区别 第一个是传统的excel 效率低 切会出现内存不够 或者列不够 适合少量的数据 
		 * 第二个表示 每次缓存写入 length 条数据 循环写  不会出现内存溢出 和其它问题
		 */
		// Workbook wb = new XSSFWorkbook();
		SXSSFWorkbook wb = new SXSSFWorkbook(length);

		/* 设置某个单元格为加粗黑体 居中 的样式 */
		Font titleFont = wb.createFont();
		titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		CellStyle titleCellStyle = wb.createCellStyle();
		titleCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		titleCellStyle.setFont(titleFont);

		// 2.0 创建一个sheet对象 excel 有多个sheet
		Sheet sheet = wb.createSheet();

		/* 合并单元格 */
		int firstRow = 0; // 起始行
		int firstCol = 0; // 起始列
		int lastRow = 0; // 结束行
		int lastCol = sheetHeader != null && sheetHeader.size() > 0 ? sheetHeader.size() - 1 : 0; // 结束列
		sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));

		// 用来记录行角标
		int rowId = 0;

		// 2.1 写入标题
		Row row = sheet.createRow(rowId++);
		Cell cell = row.createCell(0); // 获得第一个单元格
		cell.setCellValue(sheetTitle); // 设置内容
		cell.setCellStyle(titleCellStyle); // 设置样式

		// 2.2 写入 每一列的 title
		row = sheet.createRow(rowId++);
		for (int i = 0; i < sheetHeader.size(); i++) {
			row.createCell(i).setCellValue(sheetHeader.get(i).getValue() + "");
		}

		// 2.3开始循环设置内容
		for (Iterator<Map<String, Object>> iterator = data.iterator(); iterator.hasNext();) {
			Map<String, Object> map = (Map<String, Object>) iterator.next();
			row = sheet.createRow(rowId++);
			for (int i = 0; i < sheetHeader.size(); i++) {
				row.createCell(i).setCellValue(map.get(sheetHeader.get(i).getKey()) + "");
			}
		}
		/* 写出 */
		try {

			response.setContentType("application/msexcel;charset=UTF-8");
			response.setHeader("Content-Disposition",
					"attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + ".xlsx");
			OutputStream out = response.getOutputStream();
			wb.write(out);
			out.close();
			wb.dispose();
			wb.close();
		} catch (IOException e7) {
			e7.printStackTrace();
		}
	}
	/**
	 * 
	 * @param length  缓存大小  默认1000就好了
	 * @param sheetTitle  标题名称
	 * @param fileName 文件名
	 * @param sheetHeader  标题名
	 * @param data  数据
	 * @param response  响应
	 * @return
	 * @author spongeli
	 */
	public static SXSSFWorkbook getWorkBookInfo(int length, String sheetTitle,String fileName ,List<String> sheetHeader,
			List<Object> data,HttpServletResponse response) {

		// 1.0 创建一个excle对象
		/**
		 * 这两个的区别 第一个是传统的excel 效率低 切会出现内存不够 或者列不够 适合少量的数据 第二个表示 每次写入100条数据 循环写
		 * 不会出现内存溢出 和其它问题
		 */
		// Workbook wb = new XSSFWorkbook();
		SXSSFWorkbook wb = new SXSSFWorkbook(length);

		/* 设置某个单元格为加粗黑体 居中 的样式 */
		Font titleFont = wb.createFont();
		titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		CellStyle titleCellStyle = wb.createCellStyle();
		titleCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		titleCellStyle.setFont(titleFont);

		// 2.0 创建一个sheet对象 excel 有多个sheet
		Sheet sheet = wb.createSheet();

		/* 合并单元格 */
		int firstRow = 0; // 起始行
		int firstCol = 0; // 起始列
		int lastRow = 0; // 结束行
		int lastCol = sheetHeader != null && sheetHeader.size() > 0 ? sheetHeader.size() - 1 : 0; // 结束列
		sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));

		// 用来记录行角标
		int rowId = 0;

		// 2.1 写入标题
		Row row = sheet.createRow(rowId++);
		Cell cell = row.createCell(0); // 获得第一个单元格
		cell.setCellValue(sheetTitle); // 设置内容
		cell.setCellStyle(titleCellStyle); // 设置样式

		// 2.2 写入 每一列的 title
		row = sheet.createRow(rowId++);
		for (int i = 0; i < sheetHeader.size(); i++) {
			row.createCell(i).setCellValue(sheetHeader.get(i));
		}

		// 2.3开始循环设置内容
		for (Iterator<Object> iterator = data.iterator(); iterator.hasNext();) {
			Object obj = (Object) iterator.next();
			row = sheet.createRow(rowId++);
			// row.createCell(0).setCellValue(obj.getXXX());
			// row.createCell(1).setCellValue(obj.getXXX());
			// row.createCell(2).setCellValue(obj.getXXX());
		}
		/* 写出 */
		try {
			response.setContentType("application/msexcel;charset=UTF-8");
			response.setHeader("Content-Disposition",
					"attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + ".xlsx");
			OutputStream out = response.getOutputStream();
			wb.write(out);
			out.close();
			wb.dispose();
			wb.close();
		} catch (IOException e7) {
			e7.printStackTrace();
		}
		return wb;
	}

	public static void main(String[] args) throws IOException {

		List<MapEntry<String, Object>> list = new ArrayList<MapEntry<String, Object>>();
		MapEntry<String, Object> entry = new MapEntry<>();
		entry.setKey("name");
		entry.setValue("姓名");
		MapEntry<String, Object> entry2 = new MapEntry<>();
		entry2.setKey("age");
		entry2.setValue("年龄");
		list.add(entry);
		list.add(entry2);
		List<Map<String, Object>> list2 = new ArrayList<>();
		Map<String, Object> map = new HashMap<>();
		map.put("name", "李超");
		map.put("age", "23");
		Map<String, Object> map2 = new HashMap<>();
		map2.put("name", "张三");
		map2.put("age", "24");
		list2.add(map);
		list2.add(map2);
		/*
		 * SXSSFWorkbook workBook = getWorkBook(1000, "title", list, list2); //
		 * 创建文件流 OutputStream stream = new FileOutputStream("e:/test123.xlsx");
		 * // 写入数据 workBook.write(stream);
		 */
		/* workBook.close(); */
	}
}
